package model;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author Alexander Shidlovsky
 */
public class Stack implements Comparable<Stack> {
    private ProductType productType;
    private int numberOfTrays;
    private TaskInfo currentProcess;
    private Location location;
    private List<TaskInfo> tasks;

    public Stack(ProductType productType, int numberOfTrays, Location location) {
	this(productType, numberOfTrays);
	setLocation(location);
    }

    public Stack(ProductType productType, int numberOfTrays) {
	setProductType(productType);
	this.numberOfTrays = numberOfTrays;

	tasks = new ArrayList<TaskInfo>();

	List<Process> recipe = productType.getRecipe();
	for (int i = 0; i < recipe.size(); i++) {
	    tasks.add(new TaskInfo(recipe.get(i)));
	}

	currentProcess = tasks.get(0);
	tasks.get(0).setStartTime(new Date(System.currentTimeMillis()));
    }

    public ProductType getProductType() {
	return productType;
    }

    public void setProductType(ProductType productType) {
	if (this.productType != productType) {
	    if (this.productType != null) {
		this.productType.removeStack(this);
	    }
	    this.productType = productType;
	    productType.addStack(this);
	}
    }

    public int getNumberOfTrays() {
	return numberOfTrays;
    }

    public void setNumberOfTrays(int numberOfTrays) {
	this.numberOfTrays = numberOfTrays;
    }

    public TaskInfo getCurrentProcess() {
	return currentProcess;
    }

    public void setCurrentProcess(TaskInfo currentProcess) {
	this.currentProcess = currentProcess;
    }

    public boolean isProcessRunning() {
	return currentProcess == null ? false : true;
    }

    public Location getLocation() {
	return location;
    }

    public void setLocation(Location location) {
	this.location = location;
	if (location != null)
	    location.setStack(this);
    }

    public void removeLocation() {
	if (location != null)
	    location.removeStack();
	location = null;
    }

    public void startCurrentProcess() {
	currentProcess.setStartTime(new Date(System.currentTimeMillis()));
    }

    public boolean finishCurrentProcess() {
	if (currentProcess != null)
	    return currentProcess.finishProcess();

	return true;
    }

    public TaskInfo getNextProcess() {
	int index = tasks.indexOf(currentProcess);
	if (index + 1 >= tasks.size())
	    return null;
	else
	    return (tasks.get(index + 1));

    }

    public ArrayList<TaskInfo> getTasks() {
	return new ArrayList<TaskInfo>(tasks);
    }

    @Override
    public String toString() {
	return productType.getName();
    }

    /*
     * takes closest to ideal
     */
    // @Override
    // public int compareTo(Stack comp) {
    // if (this.currentProcess != null && comp.getCurrentProcess() != null) {
    // if (this.currentProcess.calculateDifferenceFromIdeal() <= comp
    // .getCurrentProcess().calculateDifferenceFromIdeal())
    // return -1;
    // }
    //
    // return 1;
    // }

    @Override
    public int compareTo(Stack comp) {
	if (comp.getCurrentProcess() == null
		|| !comp.getCurrentProcess().isInLimits())
	    return -1;

	if (this.currentProcess == null || !this.currentProcess.isInLimits())
	    return 1;

	if (this.currentProcess.calculateTimeLeft() <= comp.getCurrentProcess()
		.calculateTimeLeft()) {
	    return -1;
	}

	return 1;
    }
}
